home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 322 / patch / util.c < prev    next >
C/C++ Source or Header  |  1988-10-20  |  8KB  |  377 lines

  1. #include "EXTERN.h"
  2. #include "common.h"
  3. #include "INTERN.h"
  4. #include "util.h"
  5.  
  6. /* Rename a file, copying it if necessary. */
  7.  
  8. int
  9. move_file(from,to)
  10. char *from, *to;
  11. {
  12.     char bakname[512];
  13.     Reg1 char *s;
  14.     Reg2 int i;
  15.     Reg3 int fromfd;
  16.  
  17.     /* to stdout? */
  18.  
  19.     if (strEQ(to, "-")) {
  20. #ifdef DEBUGGING
  21.     if (debug & 4)
  22.         say2("Moving %s to stdout.\n", from);
  23. #endif
  24.     fromfd = open(from, 0);
  25.     if (fromfd < 0)
  26.         fatal2("patch: internal error, can't reopen %s\n", from);
  27.     while ((i=read(fromfd, buf, sizeof buf)) > 0)
  28.         if (write(1, buf, i) != 1)
  29.         fatal1("patch: write failed\n");
  30.     Close(fromfd);
  31.     return 0;
  32.     }
  33.  
  34.     if (origprae) {
  35.         Strcpy (bakname, origprae);
  36.         Strcat(bakname, to);
  37.     } else {
  38.            Strcpy(bakname, to);
  39. #ifdef atarist
  40.     {
  41.       int i = strlen(bakname);
  42.       
  43.       for ( ; i > 0 ; i--)
  44.           if (bakname[i] == '.')
  45.             {
  46.             bakname[i] = '\0';
  47.             break;
  48.             }
  49.     }
  50. #endif
  51.         Strcat(bakname, origext?origext:ORIGEXT);
  52.     }
  53.     if (stat(to, &filestat) >= 0) {    /* output file exists */
  54.     dev_t to_device = filestat.st_dev;
  55.     ino_t to_inode  = filestat.st_ino;
  56.     char *simplename = bakname;
  57.     
  58.     for (s=bakname; *s; s++) {
  59.         if (*s == '/')
  60.         simplename = s+1;
  61.     }
  62.     /* find a backup name that is not the same file */
  63.     while (stat(bakname, &filestat) >= 0 &&
  64.         to_device == filestat.st_dev && to_inode == filestat.st_ino) {
  65.         for (s=simplename; *s && !islower(*s); s++) ;
  66.         if (*s)
  67.         *s = toupper(*s);
  68.         else
  69.         Strcpy(simplename, simplename+1);
  70.     }
  71.     while (unlink(bakname) >= 0) ;    /* while() is for benefit of Eunice */
  72. #ifdef DEBUGGING
  73.     if (debug & 4)
  74.         say3("Moving %s to %s.\n", to, bakname);
  75. #endif
  76.     if (link(to, bakname) < 0) {
  77.         say3("patch: can't backup %s, output is in %s\n",
  78.         to, from);
  79.         return -1;
  80.     }
  81.     while (unlink(to) >= 0) ;
  82.     }
  83. #ifdef DEBUGGING
  84.     if (debug & 4)
  85.     say3("Moving %s to %s.\n", from, to);
  86. #endif
  87.     if (link(from, to) < 0) {        /* different file system? */
  88.     Reg4 int tofd;
  89.     
  90.     tofd = creat(to, 0666);
  91.     if (tofd < 0) {
  92.         say3("patch: can't create %s, output is in %s.\n",
  93.           to, from);
  94.         return -1;
  95.     }
  96.     fromfd = open(from, 0);
  97.     if (fromfd < 0)
  98.         fatal2("patch: internal error, can't reopen %s\n", from);
  99.     while ((i=read(fromfd, buf, sizeof buf)) > 0)
  100.         if (write(tofd, buf, i) != i)
  101.         fatal1("patch: write failed\n");
  102.     Close(fromfd);
  103.     Close(tofd);
  104.     }
  105.     Unlink(from);
  106.     return 0;
  107. }
  108.  
  109. /* Copy a file. */
  110.  
  111. void
  112. copy_file(from,to)
  113. char *from, *to;
  114. {
  115.     Reg3 int tofd;
  116.     Reg2 int fromfd;
  117.     Reg1 int i;
  118.     
  119.     tofd = creat(to, 0666);
  120.     if (tofd < 0)
  121.     fatal2("patch: can't create %s.\n", to);
  122.     fromfd = open(from, 0);
  123.     if (fromfd < 0)
  124.     fatal2("patch: internal error, can't reopen %s\n", from);
  125.     while ((i=read(fromfd, buf, sizeof buf)) > 0)
  126.     if (write(tofd, buf, i) != i)
  127.         fatal2("patch: write (%s) failed\n", to);
  128.     Close(fromfd);
  129.     Close(tofd);
  130. }
  131.  
  132. /* Allocate a unique area for a string. */
  133.  
  134. char *
  135. savestr(s)
  136. Reg1 char *s;
  137. {
  138.     Reg3 char *rv;
  139.     Reg2 char *t;
  140.  
  141.     if (!s)
  142.     s = "Oops";
  143.     t = s;
  144.     while (*t++);
  145.     rv = malloc((MEM) (t - s));
  146.     if (rv == Nullch) {
  147.     if (using_plan_a)
  148.         out_of_mem = TRUE;
  149.     else
  150.         fatal1("patch: out of memory (savestr)\n");
  151.     }
  152.     else {
  153.     t = rv;
  154.     while (*t++ = *s++);
  155.     }
  156.     return rv;
  157. }
  158.  
  159. #if defined(lint) && defined(CANVARARG)
  160.  
  161. /*VARARGS ARGSUSED*/
  162. say(pat) char *pat; { ; }
  163. /*VARARGS ARGSUSED*/
  164. fatal(pat) char *pat; { ; }
  165. /*VARARGS ARGSUSED*/
  166. ask(pat) char *pat; { ; }
  167.  
  168. #else
  169.  
  170. /* Vanilla terminal output (buffered). */
  171.  
  172. void
  173. say(pat,arg1,arg2,arg3)
  174. char *pat;
  175. long arg1,arg2,arg3;
  176. {
  177.     fprintf(stderr, pat, arg1, arg2, arg3);
  178.     Fflush(stderr);
  179. }
  180.  
  181. /* Terminal output, pun intended. */
  182.  
  183. void                /* very void */
  184. fatal(pat,arg1,arg2,arg3)
  185. char *pat;
  186. long arg1,arg2,arg3;
  187. {
  188.     void my_exit();
  189.  
  190.     say(pat, arg1, arg2, arg3);
  191.     my_exit(1);
  192. }
  193.  
  194. /* Get a response from the user, somehow or other. */
  195.  
  196. void
  197. ask(pat,arg1,arg2,arg3)
  198. char *pat;
  199. long arg1,arg2,arg3;
  200. {
  201.     int ttyfd;
  202.     int r;
  203.     bool tty2 = isatty(2);
  204.  
  205.     Sprintf(buf, pat, arg1, arg2, arg3);
  206.     Fflush(stderr);
  207.     write(2, buf, strlen(buf));
  208.     if (tty2) {                /* might be redirected to a file */
  209.     r = read(2, buf, sizeof buf);
  210.     }
  211.     else if (isatty(1)) {        /* this may be new file output */
  212.     Fflush(stdout);
  213.     write(1, buf, strlen(buf));
  214.     r = read(1, buf, sizeof buf);
  215.     }
  216.     else if ((ttyfd = open("/dev/tty", 2)) >= 0 && isatty(ttyfd)) {
  217.                     /* might be deleted or unwriteable */
  218.     write(ttyfd, buf, strlen(buf));
  219.     r = read(ttyfd, buf, sizeof buf);
  220.     Close(ttyfd);
  221.     }
  222.     else if (isatty(0)) {        /* this is probably patch input */
  223.     Fflush(stdin);
  224.     write(0, buf, strlen(buf));
  225.     r = read(0, buf, sizeof buf);
  226.     }
  227.     else {                /* no terminal at all--default it */
  228.     buf[0] = '\n';
  229.     r = 1;
  230.     }
  231.     if (r <= 0)
  232.     buf[0] = 0;
  233.     else
  234.     buf[r] = '\0';
  235.     if (!tty2)
  236.     say1(buf);
  237. }
  238. #endif /* lint */
  239.  
  240. /* How to handle certain events when not in a critical region. */
  241.  
  242. void
  243. set_signals(reset)
  244. int reset;
  245. {
  246.     void my_exit();
  247. #ifndef lint
  248. #ifdef VOIDSIG
  249.     static void (*hupval)(),(*intval)();
  250. #else
  251.     static int (*hupval)(),(*intval)();
  252. #endif
  253.  
  254.     if (!reset) {
  255.     hupval = signal(SIGHUP, SIG_IGN);
  256.     if (hupval != SIG_IGN)
  257. #ifdef VOIDSIG
  258.         hupval = my_exit;
  259. #else
  260.         hupval = (int(*)())my_exit;
  261. #endif
  262.     intval = signal(SIGINT, SIG_IGN);
  263.     if (intval != SIG_IGN)
  264. #ifdef VOIDSIG
  265.         intval = my_exit;
  266. #else
  267.         intval = (int(*)())my_exit;
  268. #endif
  269.     }
  270.     Signal(SIGHUP, hupval);
  271.     Signal(SIGINT, intval);
  272. #endif
  273. }
  274.  
  275. /* How to handle certain events when in a critical region. */
  276.  
  277. void
  278. ignore_signals()
  279. {
  280. #ifndef lint
  281.     Signal(SIGHUP, SIG_IGN);
  282.     Signal(SIGINT, SIG_IGN);
  283. #endif
  284. }
  285.  
  286. /* Make sure we'll have the directories to create a file. */
  287.  
  288. void
  289. makedirs(filename,striplast)
  290. Reg1 char *filename;
  291. bool striplast;
  292. {
  293.     char tmpbuf[256];
  294.     Reg2 char *s = tmpbuf;
  295.     char *dirv[20];
  296.     Reg3 int i;
  297.     Reg4 int dirvp = 0;
  298.  
  299.     while (*filename) {
  300.     if (*filename == '/') {
  301.         filename++;
  302.         dirv[dirvp++] = s;
  303.         *s++ = '\0';
  304.     }
  305.     else {
  306.         *s++ = *filename++;
  307.     }
  308.     }
  309.     *s = '\0';
  310.     dirv[dirvp] = s;
  311.     if (striplast)
  312.     dirvp--;
  313.     if (dirvp < 0)
  314.     return;
  315.     strcpy(buf, "mkdir");
  316.     s = buf;
  317.     for (i=0; i<=dirvp; i++) {
  318.     while (*s) s++;
  319.     *s++ = ' ';
  320.     strcpy(s, tmpbuf);
  321.     *dirv[i] = '/';
  322.     }
  323.     system(buf);
  324. }
  325.  
  326. /* Make filenames more reasonable. */
  327.  
  328. char *
  329. fetchname(at,strip_leading,assume_exists)
  330. char *at;
  331. int strip_leading;
  332. int assume_exists;
  333. {
  334.     char *s;
  335.     char *name;
  336.     Reg1 char *t;
  337.     char tmpbuf[200];
  338.  
  339.     if (!at)
  340.     return Nullch;
  341.     s = savestr(at);
  342.     for (t=s; isspace(*t); t++) ;
  343.     name = t;
  344. #ifdef DEBUGGING
  345.     if (debug & 128)
  346.     say4("fetchname %s %d %d\n",name,strip_leading,assume_exists);
  347. #endif
  348.     if (strnEQ(name, "/dev/null", 9))    /* so files can be created by diffing */
  349.     return Nullch;            /*   against /dev/null. */
  350.     for (; *t && !isspace(*t); t++)
  351.     if (*t == '/')
  352.         if (--strip_leading >= 0)
  353.         name = t+1;
  354.     *t = '\0';
  355.     if (name != s && *s != '/') {
  356.     name[-1] = '\0';
  357.     if (stat(s, &filestat) && filestat.st_mode & S_IFDIR) {
  358.         name[-1] = '/';
  359.         name=s;
  360.     }
  361.     }
  362.     name = savestr(name);
  363.     Sprintf(tmpbuf, "RCS/%s", name);
  364.     free(s);
  365.     if (stat(name, &filestat) < 0 && !assume_exists) {
  366.     Strcat(tmpbuf, RCSSUFFIX);
  367.     if (stat(tmpbuf, &filestat) < 0 && stat(tmpbuf+4, &filestat) < 0) {
  368.         Sprintf(tmpbuf, "SCCS/%s%s", SCCSPREFIX, name);
  369.         if (stat(tmpbuf, &filestat) < 0 && stat(tmpbuf+5, &filestat) < 0) {
  370.         free(name);
  371.         name = Nullch;
  372.         }
  373.     }
  374.     }
  375.     return name;
  376. }
  377.